package vue.panneau1;
import java.awt.*;
import java.util.List;
import java.util.Vector;
import javax.swing.*;

import modele.*;
import vue.panneau2.Zone2;
import vue.panneau2.modele.exception.IndiceIncorrectException;
import vue.panneau3.Zone3;
import vue.util.RGBMixer;
import controle.*;

public class Interface2DZone1 extends JPanel
{
	private static final long serialVersionUID = 1L;
	private Color bleu = new Color(102,204,255);
	
	// composants pour les equations
	private JTextField valeurX1,valeurX2,valeurPartieD;
	private JLabel jl1,jl2,jl3;
	private JComboBox jcbOperateur;
	private JButton bChoisirLibelles,bChoixCouleur,bAjouterEq,bSupprimerEq;
	private JTable jtEquations;
	private TableModelEquation tmEquations;
	private int equationSelectionnee;
	private Box boxEq,boxH1,boxH2,boxH3,boxV;
	
	// composants de la fonction a optimiser
	private JTextField optX1,optX2;
	private JLabel jlX1,jlX2;
	private JButton bOptimiser;
	private JComboBox jcbChoixOpt;
	private Box boxOpt;
	
	private Zone2 z2;
	private Zone3 z3;
	
	public Interface2DZone1(Zone2 z2, Zone3 z3)
	{		
		this.z2 = z2;
		this.z3 = z3;
		
		/********************** vue pour les contraintes *********************/
		
		valeurX1 = new JTextField("0",3);
		valeurX2 = new JTextField("0",3);
		valeurPartieD = new JTextField("0",3);
		
		valeurX1.setMaximumSize(valeurX1.getPreferredSize());
		valeurX2.setMaximumSize(valeurX2.getPreferredSize());
		valeurPartieD.setMaximumSize(valeurPartieD.getPreferredSize());
		
		jl1 = new JLabel("Contraintes :");
		jl2 = new JLabel(" X1 +");
		jl3 = new JLabel(" X2 ");
		
		jcbOperateur = new JComboBox();
		jcbOperateur.setPreferredSize(new Dimension(45,20));
		jcbOperateur.setMaximumSize(jcbOperateur.getPreferredSize());
		
		jcbOperateur.insertItemAt("<=",0);
		jcbOperateur.insertItemAt(">=",1);
		jcbOperateur.setSelectedIndex(0);
		
		bChoixCouleur = new JButton(" ");
		bChoixCouleur.setMaximumSize(new Dimension(40,20));
		bChoixCouleur.setBackground(Color.BLACK);
		bChoixCouleur.setFocusable(false);
		bChoixCouleur.setActionCommand("choisir_couleur");
		bChoixCouleur.addActionListener(new ControleActionEquation2D(this));
		
		bAjouterEq = new JButton("Ajouter");		
		bAjouterEq.setMaximumSize(new Dimension(80,20));
		bAjouterEq.setBackground(bleu);
		bAjouterEq.setActionCommand("ajouter");
		bAjouterEq.addActionListener(new ControleActionEquation2D(this));
		
		// box contenant l'ajout d'equation
		boxEq = Box.createHorizontalBox();
		boxEq.add(Box.createHorizontalStrut(5));
		boxEq.add(valeurX1);
		boxEq.add(Box.createHorizontalStrut(3));
		boxEq.add(jl2);
		boxEq.add(Box.createHorizontalStrut(3));
		boxEq.add(valeurX2);
		boxEq.add(Box.createHorizontalStrut(3));
		boxEq.add(jl3);
		boxEq.add(Box.createHorizontalStrut(3));
		boxEq.add(jcbOperateur);
		boxEq.add(Box.createHorizontalStrut(5));
		boxEq.add(valeurPartieD);
		boxEq.add(Box.createHorizontalStrut(5));
		boxEq.add(bChoixCouleur);
		boxEq.add(Box.createHorizontalStrut(5));
		boxEq.add(bAjouterEq);
		
		equationSelectionnee = -1;
		
		// instanciation d'un simplexe2D
		z2.getModele().creerProblemeLineaire(2);
		
		// JTable et son modele
		tmEquations = new TableModelEquation(this,false/*is3D = false*/);		
		jtEquations = new JTable(tmEquations);
		jtEquations.addMouseListener(new ControleSelectionEquation2D(this,jtEquations));		
		// mise en page de la table
		new RendererJTableEquation(jtEquations,tmEquations);
		
		// box pour le jlabel "contraintes" et le bouton choix des libelles
		bChoisirLibelles = new JButton("Changer les libellés des variables");
		bChoisirLibelles.setMaximumSize(new Dimension(225,20));
		bChoisirLibelles.setBackground(bleu);
		bChoisirLibelles.setActionCommand("choisir_libelle");
		bChoisirLibelles.addActionListener(new ControleActionEquation2D(this));	
		
		boxH1 = Box.createHorizontalBox();
		boxH1.add(Box.createHorizontalStrut(5));
		boxH1.add(jl1);	
		boxH1.add(Box.createHorizontalStrut(65));
		boxH1.add(bChoisirLibelles);		
		
		// box pour le jscrollpane contenant la jtable
		boxH2 = Box.createHorizontalBox();
		boxH2.add(Box.createHorizontalStrut(5));
		boxH2.add(new JScrollPane(jtEquations));
		
		bSupprimerEq = new JButton("Supprimer l'équation surlignée");
		bSupprimerEq.setMaximumSize(new Dimension(220,20));
		bSupprimerEq.setBackground(bleu);
		bSupprimerEq.setActionCommand("supprimer");
		bSupprimerEq.addActionListener(new ControleActionEquation2D(this));
		
		// box pour la suppression d'equation
		boxH3 = Box.createHorizontalBox();
		boxH3.add(Box.createHorizontalStrut(5));
		boxH3.add(bSupprimerEq);
		
		/*********************************************************************/
		
		/****************** vue pour la fonction a optimiser *****************/
		
		jcbChoixOpt = new JComboBox();
		jcbChoixOpt.setPreferredSize(new Dimension(89,20));
		jcbChoixOpt.setMaximumSize(jcbChoixOpt.getPreferredSize());
		
		jcbChoixOpt.insertItemAt("Minimiser",0);
		jcbChoixOpt.insertItemAt("Maximiser",1);
		jcbChoixOpt.setSelectedIndex(0);
		
		optX1 = new JTextField("0",3);
		optX2 = new JTextField("0",3);
		
		optX1.setMaximumSize(optX1.getPreferredSize());
		optX2.setMaximumSize(optX2.getPreferredSize());
		
		jlX1 = new JLabel(" X1 + ");
		jlX2 = new JLabel(" X2 ");
		
		bOptimiser = new JButton("Optimiser");
		bOptimiser.setMaximumSize(new Dimension(80,20));
		bOptimiser.setBackground(bleu);
		bOptimiser.setActionCommand("optimiser");
		bOptimiser.addActionListener(new ControleActionEquation2D(this));	
		
		boxOpt = Box.createHorizontalBox();
		boxOpt.add(Box.createHorizontalStrut(5));
		boxOpt.add(jcbChoixOpt);
		boxOpt.add(Box.createHorizontalStrut(5));
		boxOpt.add(optX1);
		boxOpt.add(Box.createHorizontalStrut(3));
		boxOpt.add(jlX1);
		boxOpt.add(Box.createHorizontalStrut(3));
		boxOpt.add(optX2);
		boxOpt.add(Box.createHorizontalStrut(3));
		boxOpt.add(jlX2);
		boxOpt.add(Box.createHorizontalStrut(3));
		boxOpt.add(bOptimiser);
		
		/*********************************************************************/
		
		// box vertical qui contient tous les boxes horizontaux
		boxV = Box.createVerticalBox();
		boxV.add(Box.createVerticalStrut(2));
		boxV.add(boxH1);
		boxV.add(Box.createVerticalStrut(5));
		boxV.add(boxEq);
		boxV.add(Box.createVerticalStrut(10));
		boxV.add(boxH2);
		boxV.add(Box.createVerticalStrut(10));
		boxV.add(boxH3);
		boxV.add(Box.createVerticalStrut(15));
		boxV.add(boxOpt);
		boxV.add(Box.createVerticalStrut(5));
		
		this.setBackground(new Color(255,153,51));
		this.setLayout(new BorderLayout(5,5));
		this.add(boxV,BorderLayout.WEST);	
		//this.add(new Zone2(),BorderLayout.CENTER);
	}
	
	public TableModelEquation getTableModelEquation()
	{
		return tmEquations;
	}
	
	public Zone2 getZone2()
	{
		return z2;
	}
	
	public Zone3 getZone3()
	{
		return z3;
	}	
	
	public String getValeurContrainte(String var)
	{
		String v = "";
		if(var.equals("x1"))
		{
			v = valeurX1.getText();		
		}
		if(var.equals("x2"))
		{
			v = valeurX2.getText();		
		}
		if(var.equals("partieD"))
		{
			v = valeurPartieD.getText();		
		}
		return v;
	}
	
	public float getFloatContrainte(String var)
	{
		float f = 0;
		
		try
		{			
			f = Float.parseFloat(this.getValeurContrainte(var));
		}
		catch(NumberFormatException e)
		{
			System.out.println("Erreur contrainte : transtypage float");
		}
		return f;
	}
	
	public String getOperateur()
	{
		return (String)jcbOperateur.getSelectedItem();
	}
	
	public void setEquationSelectionnee(int index)
	{
		equationSelectionnee = index;
		Equation2D eq = tmEquations.getEquation2DAt(index);
		valeurX1.setText("" + eq.getX1());
		valeurX2.setText("" + eq.getX2());
		jcbOperateur.setSelectedItem(eq.getOperateur());
		valeurPartieD.setText("" + eq.getPartieDroite());
		bChoixCouleur.setBackground(eq.getCouleur());
	}
	
	public Color getCouleurChoisie()
	{
		return bChoixCouleur.getBackground();
	}
	
	public void choisirCouleur()
	{
		new RGBMixer(bChoixCouleur);
	}
	
	public String obtenirLibelleX1()
	{
		return z3.getModele().getLibelleX1();		
	}
	
	public String obtenirLibelleX2()
	{
		return z3.getModele().getLibelleX2();		
	}
	
	public void choisirLibelleX1X2(String lib1,String lib2)
	{
		z3.getModele().setLibelleX1(lib1);
		z3.getModele().setLibelleX2(lib2);
		
		try 
		{
			z2.getModele().getProblemeLineaire().setNomVariable(0, lib1);
			z2.getModele().getProblemeLineaire().setNomVariable(1, lib2);
		}
		catch (IndiceIncorrectException e) 
		{
			e.printStackTrace();
		}
	}
	
	public void choisirLibelleContrainte(int index,String libelle)
	{
		tmEquations.choisirLibelleContrainte(index,libelle);
	}
	
	public void ajouterEquation(Equation2D eq)
	{
		// ajout dans la zone 1
		tmEquations.ajouterEquation2D(eq);
		
		// ajout dans la zone 3
		z3.getModele().ajouterEquation2D(eq);
		
		valeurX1.setText("0");
		valeurX2.setText("0");
		valeurPartieD.setText("0");
		bChoixCouleur.setBackground(Color.BLACK);
		
		//Pour mettre a jour le systeme d'equation de la zone 2
		creeOuRemplaceSystemeEquation2D();
	}	
	
	public void modifierEquation(Equation2D neweq,Equation2D equationCourante)
	{
		tmEquations.modifierEquation2D(neweq,equationSelectionnee);
		if(equationCourante.getCochee())
		{
			z3.getModele().modifierEquation2D(neweq,equationCourante);
		}
		
		//Pour mettre a jour le systeme d'equation de la zone 2
		creeOuRemplaceSystemeEquation2D();
	}
	
	public void supprimerEquation()
	{
		if(equationSelectionnee != -1 && tmEquations.getRowCount() != 0)
		{	
			// suppression dans la zone 3
			Equation2D eq = tmEquations.getEquation2DAt(equationSelectionnee);
			if(eq.getCochee())
			{				
				z3.getModele().supprimerEquation2D(eq);
			}
			
			// suppression dans la zone 1
			tmEquations.supprimerEquation2D(equationSelectionnee);

			//Pour mettre a jour le systeme d'equation de la zone 2
			this.creeOuRemplaceSystemeEquation2D();		
		}			
	}
	
	public void charger2D(Vector<Equation2D> listeEquations,FonctionAOptimiser2D fct2D)
	{
		tmEquations.setListeEquations2D(listeEquations);
		tmEquations.setFonctionAOptimiser2D(fct2D);
		
		z3.getModele().setFonctionAOptimiser2D(fct2D.getX1(),fct2D.getX2());
		
		for(int i=0;i<listeEquations.size();i++)
		{
			z3.getModele().ajouterEquation2D(listeEquations.elementAt(i));
		}
		
		this.creeOuRemplaceSystemeEquation2D();
	}
	
	public void charger3D(Vector<Equation3D> listeEquations,FonctionAOptimiser3D fct3D)
	{
		tmEquations.setListeEquations3D(listeEquations);
		tmEquations.setFonctionAOptimiser3D(fct3D);
		
		//z3.getModele().setFonctionAOptimiser3D(fct3D.getX1(),fct3D.getX2(),fct3D.getX3());
		
		for(int i=0;i<listeEquations.size();i++)
		{
			//z3.getModele().ajouterEquation3D(listeEquations.elementAt(i));
		}
		
		//this.creeOuRemplaceSystemeEquation3D();
	}
	
	public String getOptValeurX1X2(String var)
	{
		String v = "";
		if(var.equals("x1"))
		{
			v = optX1.getText();
		}
		if(var.equals("x2"))
		{
			v = optX2.getText();
		}
		return v;
	}
	
	public float getOptFloatX1X2(String var)
	{
		float f = 0;
		
		try
		{			
			f = Float.parseFloat(this.getOptValeurX1X2(var));
		}
		catch(NumberFormatException e)
		{
			System.out.println("Erreur fonction a optimiser : transtypage float");
		}
		return f;
	}
	
	public String getOptChoix()
	{
		return (String)jcbChoixOpt.getSelectedItem();
	}
	
	public void optimiser(FonctionAOptimiser2D fct)
	{		
		tmEquations.setFonctionAOptimiser2D(fct);
		z3.getModele().setFonctionAOptimiser2D(fct.getX1(),fct.getX2());

		//Pour mettre a jour le systeme d'equation de la zone 2
		this.creeOuRemplaceSystemeEquation2D();
	}
	
	private void creeOuRemplaceSystemeEquation2D() 
	{
		SystemeDeSimplexe2D sds = tmEquations.getSystemDS2D();
		
		List<Equation2D> listeEquation2D = sds.getListeEquations();
		FonctionAOptimiser2D fctAOptimiser = sds.getFonctionAOptimiser2D();
		
		z2.getModele().setSystemeEquation2D(listeEquation2D, fctAOptimiser);
		
		//Pour actualiser la zone 2
		z2.repaint();
	}
}